﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;


namespace StarWarsGame
{
    class DrawClass
    {
        private Game _game;

        public Game Game
        {
            get { return _game; }
            set { _game = value; }
        }
       
        public void DrawTargets(List<BoundingSphere> targetList, Model targetModel)
        {
            for (int i = 0; i < targetList.Count; i++)
            {
                Matrix worldMatrix = Matrix.CreateScale(targetList[i].Radius) * Matrix.CreateTranslation(targetList[i].Center);

                Matrix[] targetTransforms = new Matrix[targetModel.Bones.Count];
                targetModel.CopyAbsoluteBoneTransformsTo(targetTransforms);
                foreach (ModelMesh mesh in targetModel.Meshes)
                {
                    foreach (Effect currentEffect in mesh.Effects)
                    {
                        currentEffect.CurrentTechnique = currentEffect.Techniques["Colored"];
                        currentEffect.Parameters["xWorld"].SetValue(targetTransforms[mesh.ParentBone.Index] * worldMatrix);
                        currentEffect.Parameters["xView"].SetValue(Game.viewMatrix);
                        currentEffect.Parameters["xProjection"].SetValue(Game.projectionMatrix);
                        currentEffect.Parameters["xEnableLighting"].SetValue(true);
                        currentEffect.Parameters["xLightDirection"].SetValue(Game.lightDirection);
                        currentEffect.Parameters["xAmbient"].SetValue(0.5f);
                    }
                    mesh.Draw();
                }
            }
        }

        public void DrawBullets(List<Bullet> bulletList)
        {
            if (bulletList.Count > 0)
            {

                VertexPositionColor[] SpriteArray = new VertexPositionColor[bulletList.Count];
                for (int i = 0; i < bulletList.Count; i++)
                    SpriteArray[i] = new VertexPositionColor(bulletList[i].bulletPosition, Color.WhiteSmoke);

                Game.graphics.GraphicsDevice.RenderState.PointSpriteEnable = true;
                Game.graphics.GraphicsDevice.RenderState.PointSize = 64.0f;

                Game.graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true;
                Game.graphics.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
                Game.graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.One;
                Game.graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;

                Game.graphics.GraphicsDevice.VertexDeclaration = Game.pointSpriteVertexDeclaration;
                Matrix WVPMatrix = Matrix.Identity * Game.viewMatrix * Game.projectionMatrix;
                Game.pointSpritesEffect.Parameters["WVPMatrix"].SetValue(WVPMatrix);

                Game.pointSpritesEffect.Begin();
                foreach (EffectPass pass in Game.pointSpritesEffect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    Game.graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.PointList,
                       SpriteArray, 0, SpriteArray.Length);

                    pass.End();
                }
                Game.pointSpritesEffect.End();

                Game.graphics.GraphicsDevice.RenderState.PointSpriteEnable = false;


                Game.graphics.GraphicsDevice.RenderState.AlphaBlendEnable = false;
                Game.graphics.GraphicsDevice.RenderState.SourceBlend = Blend.One;
                Game.graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;
                Game.graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;

            }
        }

        public void DrawBullet(Bullet bullet)
        {
           
                VertexPositionColor[] SpriteArray = new VertexPositionColor[1];
                SpriteArray[0] = new VertexPositionColor(bullet.bulletPosition, Color.WhiteSmoke);

                Game.graphics.GraphicsDevice.RenderState.PointSpriteEnable = true;
                Game.graphics.GraphicsDevice.RenderState.PointSize = 64.0f;

                Game.graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true;
                Game.graphics.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
                Game.graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.One;
                Game.graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;

                Game.graphics.GraphicsDevice.VertexDeclaration = Game.pointSpriteVertexDeclaration;
                Matrix WVPMatrix = Matrix.Identity * Game.viewMatrix * Game.projectionMatrix;
                Game.pointSpritesEffect.Parameters["WVPMatrix"].SetValue(WVPMatrix);

                Game.pointSpritesEffect.Begin();
                foreach (EffectPass pass in Game.pointSpritesEffect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    Game.graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.PointList,
                       SpriteArray, 0, SpriteArray.Length);

                    pass.End();
                }
                Game.pointSpritesEffect.End();

                Game.graphics.GraphicsDevice.RenderState.PointSpriteEnable = false;


                Game.graphics.GraphicsDevice.RenderState.AlphaBlendEnable = false;
                Game.graphics.GraphicsDevice.RenderState.SourceBlend = Blend.One;
                Game.graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;
                Game.graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;

            
        }

        public void DrawATSTBullets(List<Bullet> ATSTBulletList)
        {
            if (ATSTBulletList.Count > 0)
            {

                VertexPositionColor[] SpriteArray = new VertexPositionColor[ATSTBulletList.Count];
                for (int i = 0; i < ATSTBulletList.Count; i++)
                    SpriteArray[i] = new VertexPositionColor(ATSTBulletList[i].bulletPosition, Color.WhiteSmoke);

                Game.graphics.GraphicsDevice.RenderState.PointSpriteEnable = true;
                Game.graphics.GraphicsDevice.RenderState.PointSize = 64.0f;

                Game.graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true;
                Game.graphics.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
                Game.graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.One;
                Game.graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;

                Game.graphics.GraphicsDevice.VertexDeclaration = Game.pointSpriteVertexDeclaration;
                Matrix WVPMatrix = Matrix.Identity * Game.viewMatrix * Game.projectionMatrix;
                Game.pointSpritesEffect.Parameters["WVPMatrix"].SetValue(WVPMatrix);

                Game.pointSpritesEffect.Begin();
                foreach (EffectPass pass in Game.pointSpritesEffect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    Game.graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.PointList,
                       SpriteArray, 0, SpriteArray.Length);

                    pass.End();
                }
                Game.pointSpritesEffect.End();

                Game.graphics.GraphicsDevice.RenderState.PointSpriteEnable = false;              

                Game.graphics.GraphicsDevice.RenderState.AlphaBlendEnable = false;
                Game.graphics.GraphicsDevice.RenderState.SourceBlend = Blend.One;
                Game.graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;
                Game.graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;

            }
        }

        public void DrawEnemyBullets(List<Bullet> enemyBulletList)
        {
            if (enemyBulletList.Count > 0)
            {

                VertexPositionColor[] SpriteArray = new VertexPositionColor[enemyBulletList.Count];
                for (int i = 0; i < enemyBulletList.Count; i++)
                    SpriteArray[i] = new VertexPositionColor(enemyBulletList[i].bulletPosition, Color.WhiteSmoke);

                Game.graphics.GraphicsDevice.RenderState.PointSpriteEnable = true;
                Game.graphics.GraphicsDevice.RenderState.PointSize = 64.0f;

                Game.graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true;
                Game.graphics.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
                Game.graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.One;
                Game.graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = false;

                Game.graphics.GraphicsDevice.VertexDeclaration = Game.pointSpriteVertexDeclaration;
                Matrix WVPMatrix = Matrix.Identity * Game.viewMatrix * Game.projectionMatrix;
                Game.pointSpritesEffect.Parameters["WVPMatrix"].SetValue(WVPMatrix);

                Game.pointSpritesEffect.Begin();
                foreach (EffectPass pass in Game.pointSpritesEffect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    Game.graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.PointList,
                       SpriteArray, 0, SpriteArray.Length);

                    pass.End();
                }
                Game.pointSpritesEffect.End();

                Game.graphics.GraphicsDevice.RenderState.PointSpriteEnable = false;



                Game.graphics.GraphicsDevice.RenderState.AlphaBlendEnable = false;
                Game.graphics.GraphicsDevice.RenderState.SourceBlend = Blend.One;
                Game.graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;
                Game.graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;

            }
        }

        public void DrawSkybox(Model skyboxModel, Vector3 xwingPosition, Texture2D[] skyboxTextures)
        {
            Game.device.SamplerStates[0].AddressU = TextureAddressMode.Clamp;
            Game.device.SamplerStates[0].AddressV = TextureAddressMode.Clamp;

            Game.device.RenderState.DepthBufferWriteEnable = false;
            Matrix[] skyboxTransforms = new Matrix[skyboxModel.Bones.Count];
            skyboxModel.CopyAbsoluteBoneTransformsTo(skyboxTransforms);
            int i = 0;
            foreach (ModelMesh mesh in skyboxModel.Meshes)
            {
                foreach (Effect currentEffect in mesh.Effects)
                {
                    Matrix worldMatrix = skyboxTransforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(xwingPosition);
                    currentEffect.CurrentTechnique = currentEffect.Techniques["Textured"];
                    currentEffect.Parameters["xWorld"].SetValue(worldMatrix);
                    currentEffect.Parameters["xView"].SetValue(Game.viewMatrix);
                    currentEffect.Parameters["xProjection"].SetValue(Game.projectionMatrix);
                    currentEffect.Parameters["xTexture"].SetValue(skyboxTextures[i++]);
                }
                mesh.Draw();
            }
            Game.device.RenderState.DepthBufferWriteEnable = true;
        }

        public void DrawCity(Texture2D sceneryTexture, VertexDeclaration texturedVertexDeclaration, VertexBuffer cityVertexBuffer)
        {
            Game.effect.CurrentTechnique = Game.effect.Techniques["Textured"];
            Game.effect.Parameters["xWorld"].SetValue(Matrix.Identity);
            Game.effect.Parameters["xView"].SetValue(Game.viewMatrix);
            Game.effect.Parameters["xProjection"].SetValue(Game.projectionMatrix);
            Game.effect.Parameters["xTexture"].SetValue(sceneryTexture);
            Game.effect.Parameters["xEnableLighting"].SetValue(true);
            Game.effect.Parameters["xLightDirection"].SetValue(Game.lightDirection);
            Game.effect.Parameters["xAmbient"].SetValue(0.5f);
            Game.effect.Begin();
            foreach (EffectPass pass in Game.effect.CurrentTechnique.Passes)
            {
                pass.Begin();
                Game.device.VertexDeclaration = texturedVertexDeclaration;
                Game.device.Vertices[0].SetSource(cityVertexBuffer, 0, VertexPositionNormalTexture.SizeInBytes);
                Game.device.DrawPrimitives(PrimitiveType.TriangleList, 0, cityVertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes / 3);
                pass.End();
            }
            Game.effect.End();
        }

        public void DrawXwing(Model xwingModel, Quaternion xwingRotation, Vector3 xwingPosition, Matrix[] modelTransforms)
        {
            Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(xwingRotation) * Matrix.CreateTranslation(xwingPosition);
            //float time = (float)gameTime.TotalRealTime.TotalMilliseconds / 1000.0f;
            //Matrix worldMatrix = Matrix.CreateScale(0.005f) * Matrix.CreateTranslation(7.0f, 0, 0) * Matrix.CreateRotationY(-time);
            Matrix[] xwingTransforms = new Matrix[xwingModel.Bones.Count];
            xwingModel.CopyAbsoluteBoneTransformsTo(xwingTransforms);

            xwingModel.CopyAbsoluteBoneTransformsTo(modelTransforms);
            foreach (ModelMesh mesh in xwingModel.Meshes)
            {
                // foreach (Effect currentEffect in mesh.Effects)
                for (int index = 0; index < mesh.Effects.Count; index++)
                {
                    Effect currentEffect = mesh.Effects[index] as Effect;
                    if (currentEffect != null)
                    {
                        currentEffect.CurrentTechnique = currentEffect.Techniques["Colored"];
                        currentEffect.Parameters["xWorld"].SetValue(xwingTransforms[mesh.ParentBone.Index] * worldMatrix);
                        currentEffect.Parameters["xView"].SetValue(Game.viewMatrix);
                        currentEffect.Parameters["xProjection"].SetValue(Game.projectionMatrix);
                        currentEffect.Parameters["xEnableLighting"].SetValue(true);
                        currentEffect.Parameters["xLightDirection"].SetValue(Game.lightDirection);
                        currentEffect.Parameters["xAmbient"].SetValue(0.5f);
                    }
                }
                mesh.Draw();
            }          
        }

        public void DrawATST(Model ATSTModel, Matrix[] atstModelTransforms, Vector3 ATSTposition, Quaternion ATSTRotation)
        {
            ATSTModel.CopyAbsoluteBoneTransformsTo(atstModelTransforms);

            Matrix worldMatrix = Matrix.CreateScale(0.0020f, 0.0020f, 0.0020f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(ATSTRotation) * Matrix.CreateTranslation(ATSTposition);


            foreach (ModelMesh mesh in ATSTModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = atstModelTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = Game.viewMatrix;
                    effect.Projection = Game.projectionMatrix;
                }
                mesh.Draw();
            }         
        }

        public void DrawEnemy(Model enemyModel, Matrix[] enemyModelTransforms, Quaternion enemyRotation, Vector3 enemyPosition)
        {

            enemyModel.CopyAbsoluteBoneTransformsTo(enemyModelTransforms);

            Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(enemyRotation) * Matrix.CreateTranslation(enemyPosition);


            foreach (ModelMesh mesh in enemyModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = enemyModelTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = Game.viewMatrix;
                    effect.Projection = Game.projectionMatrix;
                }
                mesh.Draw();
            }          
        }

        public void DrawRebel(Model rebelModel, Matrix[] rebelModelTransforms, Quaternion rebelRotation, Vector3 rebelPosition)
        {

            rebelModel.CopyAbsoluteBoneTransformsTo(rebelModelTransforms);

            Matrix worldMatrix = Matrix.CreateScale(0.0022f, 0.0022f, 0.0022f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(rebelRotation) * Matrix.CreateTranslation(rebelPosition);


            foreach (ModelMesh mesh in rebelModel.Meshes)
            {
                //Microsoft.Xna.Framework.Content.EffectMaterial
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = rebelModelTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = Game.viewMatrix;
                    effect.Projection = Game.projectionMatrix;
                }
                mesh.Draw();
            }
        }
    }
}
